package com.android.lovely.ui.activity

import android.content.Intent
import android.graphics.Bitmap
import android.net.Uri
import android.os.Bundle
import com.android.lovely.databinding.ActivityUploadBinding
import com.android.lovely.framework.BaseActivity
import com.kotlin.extensions.context.ActivityExt.transparentNaviBar
import com.kotlin.extensions.context.ActivityExt.transparentStatusBar
import com.kotlin.extensions.view.ViewExt.addStatusBarMarginTop
import com.kotlin.extensions.view.ViewExt.clickable
import com.yalantis.ucrop.UCrop
import com.yalantis.ucrop.callback.BitmapCropCallback
import com.yalantis.ucrop.view.CropImageView
import com.yalantis.ucrop.view.TransformImageView.TransformImageListener

/**
 * 上传图片活动类，处理图片的裁剪和保存
 *
 * @author why
 * @date 2025/3/9 21:38
 */
open class UpLoadActivity : BaseActivity<ActivityUploadBinding>() {

    companion object {
        // 最大结果图像尺寸
        private const val MAX_RESULT_IMAGE_SIZE = 1024
        // 压缩质量
        private const val COMPRESS_QUALITY = 100
        // 默认宽高比的 X 值
        private const val DEFAULT_ASPECT_RATIO_X = 1
        // 默认宽高比的 Y 值
        private const val DEFAULT_ASPECT_RATIO_Y = 1
    }

    // 从意图中获取的宽高比的 X 值
    private val aspectRatioX by lazy { intent.getIntExtra(UCrop.EXTRA_ASPECT_RATIO_X, DEFAULT_ASPECT_RATIO_X) }
    // 从意图中获取的宽高比的 Y 值
    private val aspectRatioY by lazy { intent.getIntExtra(UCrop.EXTRA_ASPECT_RATIO_Y, DEFAULT_ASPECT_RATIO_Y) }
    // 从意图中获取是否为圆形裁剪的标志
    private val isCircleCrop by lazy { intent.getBooleanExtra(UCrop.Options.EXTRA_CIRCLE_DIMMED_LAYER, false) }

    override fun initView(savedInstanceState: Bundle?) {
        setupStatusAndNavigationBar()
        setupViewMargins()
        setupImageLoadingListener()
        setupMaxImageResultSize()
        setupImageData(intent)
        setupButtonClickListeners()
    }

    /**
     * 设置状态栏和导航栏为透明
     */
    private fun setupStatusAndNavigationBar() {
        transparentStatusBar()
        transparentNaviBar()
    }

    /**
     * 设置视图的外边距
     */
    private fun setupViewMargins() {
        mBinding.backButton.addStatusBarMarginTop()
    }

    /**
     * 设置图片加载监听器
     */
    private fun setupImageLoadingListener() {
        mBinding.imageCropView.cropImageView.setTransformImageListener(imageLoadingListener)
    }

    /**
     * 设置最大图像结果尺寸
     */
    private fun setupMaxImageResultSize() {
        if (aspectRatioX == DEFAULT_ASPECT_RATIO_X && aspectRatioY == DEFAULT_ASPECT_RATIO_Y) {
            mBinding.imageCropView.cropImageView.setMaxResultImageSizeX(MAX_RESULT_IMAGE_SIZE)
            mBinding.imageCropView.cropImageView.setMaxResultImageSizeY(MAX_RESULT_IMAGE_SIZE)
        }
    }

    /**
     * 设置按钮点击监听器
     */
    private fun setupButtonClickListeners() {
        mBinding.backButton.clickable { onBackPressedDispatcher.onBackPressed() }
        mBinding.confirmButton.clickable { cropAndSaveImage() }
    }

    /**
     * 设置图片数据
     * @param intent 传入的意图，包含图片的输入和输出 URI
     */
    private fun setupImageData(intent: Intent) {
        setupTargetAspectRatio()
        val inputImageUri = intent.getParcelableExtra<Uri>(UCrop.EXTRA_INPUT_URI)
        val outputImageUri = intent.getParcelableExtra<Uri>(UCrop.EXTRA_OUTPUT_URI)
        setupCropImageViewSettings()
        setupOverlayViewSettings()

        if (inputImageUri != null && outputImageUri != null) {
            runCatching {
                mBinding.imageCropView.cropImageView.setImageUri(inputImageUri, outputImageUri)
            }.onFailure {
                setResultWithError(it)
                finish()
            }
        } else {
            finish()
        }
    }

    /**
     * 设置目标宽高比
     */
    private fun setupTargetAspectRatio() {
        if (aspectRatioX >= 0 && aspectRatioY >= 0) {
            val targetRatio: Float = aspectRatioX.toFloat() / aspectRatioY.toFloat()
            mBinding.imageCropView.cropImageView.setTargetAspectRatio(
                if (java.lang.Float.isNaN(targetRatio)) CropImageView.SOURCE_IMAGE_ASPECT_RATIO else targetRatio
            )
        }
    }

    /**
     * 设置裁剪图像视图的设置
     */
    private fun setupCropImageViewSettings() {
        mBinding.imageCropView.cropImageView.isScaleEnabled = true
        mBinding.imageCropView.cropImageView.isRotateEnabled = false
    }

    /**
     * 设置覆盖视图的设置
     */
    private fun setupOverlayViewSettings() {
        mBinding.imageCropView.overlayView.apply {
            setShowCropGrid(false)
            if (isCircleCrop) {
                setShowCropFrame(false)
                setCircleDimmedLayer(isCircleCrop)
            }
        }
    }

    // 图片加载监听器
    private val imageLoadingListener: TransformImageListener = object : TransformImageListener {
        override fun onRotate(currentAngle: Float) {}
        override fun onScale(currentScale: Float) {}
        override fun onLoadComplete() {}
        override fun onLoadFailure(e: Exception) {
            setResultWithError(e)
            finish()
        }
    }

    /**
     * 裁剪并保存图片
     */
    private fun cropAndSaveImage() {
        mBinding.imageCropView.cropImageView.cropAndSaveImage(
            Bitmap.CompressFormat.PNG,
            COMPRESS_QUALITY,
            object : BitmapCropCallback {
                override fun onBitmapCropped(
                    resultUri: Uri,
                    offsetX: Int,
                    offsetY: Int,
                    imageWidth: Int,
                    imageHeight: Int
                ) {
                    setResultWithUri(
                        resultUri,
                        mBinding.imageCropView.cropImageView.targetAspectRatio,
                        offsetX,
                        offsetY,
                        imageWidth,
                        imageHeight
                    )
                    finish()
                }

                override fun onCropFailure(t: Throwable) {
                    setResultWithError(t)
                    finish()
                }
            }
        )
    }

    /**
     * 设置结果 URI
     * @param uri 裁剪后的图片 URI
     * @param resultAspectRatio 裁剪后的宽高比
     * @param offsetX X 轴偏移量
     * @param offsetY Y 轴偏移量
     * @param imageWidth 图片宽度
     * @param imageHeight 图片高度
     */
    private fun setResultWithUri(
        uri: Uri?,
        resultAspectRatio: Float,
        offsetX: Int,
        offsetY: Int,
        imageWidth: Int,
        imageHeight: Int
    ) {
        setResult(
            RESULT_OK,
            Intent().apply {
                putExtra(UCrop.EXTRA_OUTPUT_URI, uri)
                putExtra(UCrop.EXTRA_OUTPUT_CROP_ASPECT_RATIO, resultAspectRatio)
                putExtra(UCrop.EXTRA_OUTPUT_IMAGE_WIDTH, imageWidth)
                putExtra(UCrop.EXTRA_OUTPUT_IMAGE_HEIGHT, imageHeight)
                putExtra(UCrop.EXTRA_OUTPUT_OFFSET_X, offsetX)
                putExtra(UCrop.EXTRA_OUTPUT_OFFSET_Y, offsetY)
            }
        )
    }

    /**
     * 设置结果错误
     * @param throwable 异常信息
     */
    protected fun setResultWithError(throwable: Throwable?) {
        setResult(UCrop.RESULT_ERROR, Intent().putExtra(UCrop.EXTRA_ERROR, throwable))
    }
}
